package Logica;

import java.util.List;
import java.util.Random;
import Logica.Calculos;
import Modelo.Casillero;
import Principal.Main;

public class Softmax {
	
	public Softmax(){	}
	
	static List <Casillero> vecinosAgente;
	static List <Casillero> vecinosCasEleg;
	
	public static void ejecutarSoftmax(int posActualX, int posActualY,int tau, double gamma ){//obtiene el siguiente casillero donde se movera el agente segun una probabilidad
		 
		 Casillero casilleroActual = new Casillero();
		 casilleroActual.posCasX = posActualX;
		 casilleroActual.posCasY = posActualY;
		 vecinosAgente = casilleroActual.DevolverVecinos();
		 double qVecinosAgente [] = new double[vecinosAgente.size()];
		 
		 for (int i = 0; i < vecinosAgente.size(); i++) {
	            qVecinosAgente[i] = Main.matrizauxQ[casilleroActual.posCasX][casilleroActual.posCasY][(vecinosAgente.get(i)).movrelativo] ;
	     }
		 
	
	
		 double prob[] = new double[qVecinosAgente.length];
         double sumProb = 0;
       
	     for (int i = 0; i< qVecinosAgente.length ; i++) {//
		 prob[i] = Math.exp(qVecinosAgente[i] / tau);
         sumProb += prob[i];
         }
   
	     for (int i = 0; i < qVecinosAgente.length; i++) {
         prob[i] = Main.redondeo(prob[i] / sumProb, 4);
         }
	   
	    
	     Random x = new Random();
         double numAleat = x.nextDouble();
         double numRedond = Main.redondeo(numAleat, 4);
         double limiteInterv = 0;
         Casillero casilleroElegido = new Casillero();;
       
        
         for (int i= 0; i <prob.length; i++) {
            if (numRedond> limiteInterv && numRedond < limiteInterv + prob[i]) {
               casilleroElegido = vecinosAgente.get(i);
              
            }
           
            limiteInterv += prob[i];
           
           
         }
        
        
         Main.robot.posAgX = casilleroElegido.posCasX;
 		 Main.robot.posAgY = casilleroElegido.posCasY;	
 		 vecinosCasEleg = casilleroElegido.DevolverVecinos();
 		 double maximoQ = 0;
 		
 		for (Casillero qDevecinos: vecinosCasEleg){
 			if (Main.matrizauxQ[casilleroElegido.posCasX][casilleroElegido.posCasY][qDevecinos.movrelativo] > maximoQ){
 				maximoQ = Main.matrizauxQ[casilleroElegido.posCasX][casilleroElegido.posCasY][qDevecinos.movrelativo];
 			}
 		}
 		 double recompensa = Main.matrizR[Main.robot.posAgX][Main.robot.posAgY];
         Calculos.actualizarmatrizQ(casilleroActual, casilleroElegido, recompensa, maximoQ, gamma);
	   
	 }   
	   
	 
		   
}
	   


